PowerClassQueryDevice demonstrates a method for identifying attached USB Power Class devices and accessing the information in the device's usage tables. For information on the USB Power Class, refer to the "Universal Serial Bus Usage Tables for HID Power Devices". You can find a copy of this document from the USB-IF Developer documents web page <http://www.usb.org/developers/devclass.html>. This sample assumes that the developer understands the implementation of the collections of HID usages defined for the device.
The default support provided by the Mac OS USB Power Class is to detect the presence of a USB Power Class HID device, specifically a UPS (Uninterruptible Power Supply) and periodically query the device to detect if the backup power is discharging, and if so whether the level of power remaining has decreased to a programmatically defined limit. When power falls below the "Alert" level, the Mac OS Power Class Driver informs the Power Manager of this low power condition. The Power Manager displays a low power alert to the user. If the power level continues to decrease, the Power Class driver uses Power Manager 2.0 to shutdown the system.
This program sample demonstrates the basic programming required for a UPS vendor to develop a utility appllication or control panel to report the current status of the device and to modify programmable parameters in the Power Class HID usage tables.
Requirements
This program sample was built using CodeWarrior 4.0, IDE 3.2, with the Universal Interfaces and Libraries v3.3, and the Mac OS USB DDK v1.4.1.
This program has been tested on a PowerBook G3 Series system with ADS USB Cardbus card installed running SSW 9.0 and USB v1.4.1f2 with an APS UPS device attached.
Implementation
The PowerClassQueryDevice demonstrates the use of three calls -
GetNextPowerDevice - to identify attached Power Class HID devices
Use GetNextPowerDevice to find all of the Power Class devices and to obtain the USBReference value that is required for the other Power Class device calls.
device - a pointer to a PowerDeviceDescriptor structure. On input, set the device.reference field to the USBReference for the current device. GetNextPowerDevice fills in the PowerDeviceDescriptor structure with information for the next power class device. To begin the search, set device.reference to kNoDeviceRef.
on return for the call, if the result is noErr,
device.vendor - device's vendor ID
device.product - device's product ID
device.version - device's version
device.reference - device's USBReference
Result Codes
noErr 0 - no error
kUSBNoDeviceErr -6990 - device referenced by device.reference, was not found
Use USBPowerSetUsageData to set the usage value for the specified collection, usage page and usage. USBPowerSetUsageData calls HIDSetUsageValue to set the usage value.
reference - USBReference for the specified power class device.
inCollection - index of the collection to find the desired usage. Set the index to zero to search in the default collection.
inUsagePage - usage page on which to search.
inUsage - specific usage to set value for.
on return from the call, if the result is noErr, the new value was set for the specified usage.
Result Codes
noErr 0 - no error
kUSBPending 1 - the HID request to obtain this value, is pending
memFullErr -108 - insufficient memory to allocate temporary storage
kHIDUsageNotFoundErr -13946 - specified usage not found on usagepage/collection
kUSBUnknownDeviceErr -6998 - device referenced by device.reference, was not found
(Errors returned by HIDSetUsageValue are also possible).
Using PowerClassQueryDevice
The sample program presents the user with the list of USBReferences for attached Power Class devices. Enter the USBReference value for the device you which to query. You must specify whether to get or set a usage value. Whether you set of get a usage value, you must enter the collection number, usage page and usage as hex numbers. For example, if the first collection contains the PowerDevice usages and I'm interested in the percent load of the power class device, I would enter the following
Collection: 1
Usage Page: 84 (0x84 is the usage page for PowerDevices - refer to PowerClass.h)
Usage: 35 (0x35 is the usage ID for "Percent Load" - refer to PowerClass.h)
If you have called USBPowerGetUsageData, then the percent load or error result will be displayed. If you have called USBPowerSetUsageData, then the error status in making the call is displayed.
It is assumed that the hardware developer will know the collection value to enter for their device in this case. For other developers, the preferred method for accessing the usage information is to use the HID Library API.
For comments and bug reports on the USB specific sections of the sample, mail
<dts@apple.com> with "attn: rkubota" as the first line, and I will try to address them.